﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuickRunnable
{
    public interface  Key {

        int FieldCount { get; }
        Object GetFieldValue( int index );

        int KeyPartCount { get; }
        Key GetKeyPart( int index );

        Object GetAssociatedValue( int index );
        bool HasAssociatedValue( int index );

        bool Equals( Key rhs );
    }

    public interface ExternalUniqueKey : Key {
        // FieldCount = n
        // KeyPartCount = 1
        // HasAssociatedValue( 1 ){ return value; }
    }

    public interface AdhocKey : Key {
        // FieldCount = n;
        // KeyPartCount = 1;
        // HasAssociatedValue( n ){ return false; }
    }

    public interface CombinedKey : Key
    {
        // FieldCount = sum( n.FieldCount )
        // KeyPartCount = n
        // HasAssociatedValue( n ){ }
    }

    public interface KeySubset : Key {
        // FieldCount = n
        // KeyPartcount = i
        // HasAssociatedValue( i ){ }
    }

    public class ColumnSet {
        private Column[] Columns;
        private bool[] IsNullAllowed;
        public KeySubset DeriveKey( Key input ){}
    }

    // we can define other keys or methods for creating and combining them, but they should always take a key as input or be adhoc.

    public interface IStreamingSet { }
    
    
    public class ChangeArgs {
        ChangeType ChangeType { get; }
        IEnumerable<ChangeItem> Items { get; }
        
        public class ChangeItem {
            public Key New;
            public Key Old;
        }
    }


    // our subset
    public class SetProduct : IStreamingSet {
        private SetProductCache[] m_Caches;
        
        /// <summary> Our Implementation. This stuff should be aligned, so this makes it easier. </summary>
        private class SetProductCache {
            private IStreamingSet m_InputStreamingSet;
            private List< Key > m_OutputPrepCache;
            private List< Key > m_ResultingSet;
        }
    }
    
    /// <summary> Notification and storage. </summary>
    public class Set : IStreamingSet { }
    
    /// <summary> Previously: Index. Slices up a set according to the KeyProvider. </summary>
    public class SetDefinition {
        private IStreamingSet m_Input;

        private ColumnSet m_Definition;

        private HashSet< Subset > m_Results;

        /// <summary> A Set that's associated with a given Key. IndexBucket </summary>
        public class Subset : IStreamingSet { }

        public Action< IStreamingSet > SetCreated;
    }

}
